package wfb.wfbdbimpl;

import wfb.definitions.*;

import java.util.*;

/** Schnittstelle, die von der Zugriffsschicht auf
 * die WorldFactbook-Datenbank implementiert werden muss.
 */
public class DummyImpl implements WfbDbInterface {
	
	Properties prop = null;

  private String [] sqlHead1 = {"1","2"};
  private String [][] sqlRows1 = {{"one","two"},{"three","four"}};
  
  private String [] sqlHead2 = {"Nummer","Person", "Abteilung"};
  private String [][] sqlRows2 = {{"1","Hans", "Produktion"},
                                  {"2","Fritz", "Produktion"},
                                  {"3","Lisa", "Finanzen"}};
  
  private String [] sqlHead3 = {"Update count"};
  private String [][] sqlRows3 = {{"3"}};

  private String [] statAttrs = {"BIP", "Einwohner", "Lebenserwartung-M�nner",
                                 "Lebenserwartung-Frauen"};
  private String [] statYears = {"1999", "2000"};
  
  private final String COUNTRY_NAME_DE = "Germany";
  private final String COUNTRY_NAME_FR = "France";
  private final String COUNTRY_NAME_IT = "Italy";
  
  private String[] countries = {COUNTRY_NAME_DE, COUNTRY_NAME_FR, COUNTRY_NAME_IT};
  
  
  private String[] statFrance2000 = {"1448000000000","59551227","75.01","83.01"};
  private String[] statGermany2000 = {"1936000000000","83029536","74.47","80.92"};
  private String[] statItaly2000 = {"1273000000000","57679825","75.97","82.52"};

  private String[] statFrance1999 = {"1320000000000 ","58978172","74.76","82.71"};
  private String[] statGermany1999 = {"1813000000000","82087361","74.01","80.5"};
  private String[] statItaly1999 = {"1181000000000","56735130","75.4 ","81.82"};
  
  private String[] orgFrance = {"ACCT", "AfDB", "AsDB", "Australia Group", "BDEAC", "BIS", "CCC", "CDB (non-regional)",
                                "CE", "CERN", "EAPC", "EBRD", "ECA (associate)", "ECE", "ECLAC", "EIB", "EMU", "ESA",
                                "ESCAP", "EU", "FAO", "FZ", "G- 5", "G- 7", "G-10", "IADB", "IAEA", "IBRD", "ICAO", "ICC",
                                "ICFTU", "ICRM", "IDA", "IEA", "IFAD", "IFC", "IFRCS", "IHO", "ILO", "IMF", "IMO", "Inmarsat", "InOC",
                                "Intelsat", "Interpol", "IOC", "IOM", "ISO", "ITU", "MINURSO", "MIPONUH", "MONUC", "NAM (guest)", "NATO", "NEA", "NSG", "OAS (observer)", "OECD", "OPCW", "OSCE", "PCA", "SPC",
                                "UN", "UN Security Council", "UNCTAD", "UNESCO", "UNHCR", "UNIDO", "UNIFIL",
                                "UNIKOM", "UNITAR", "UNMEE", "UNMIBH", "UNMIK", "UNOMIG", "UNRWA", "UNTAET",
                                "UNTSO", "UNU", "UPU", "WADB (nonregional)", "WCL", "WEU", "WFTU", "WHO", "WIPO",
                                "WMO", "WToO", "WTrO", "ZC"};
  private String[] orgGermany = {"AfDB : African Development Bank", "AsDB", "Australia Group", "BDEAC", "BIS", "CBSS", "CCC", "CDB (non-regional)", "CE", "CERN",
                                 "EAPC", "EBRD", "ECE", "EIB", "EMU", "ESA", "EU", "FAO", "G-5 : Group of 5", "G-7", "G-10", "IADB", "IAEA", "IBRD", "ICAO",
                                 "ICC", "ICFTU", "ICRM", "IDA", "IEA", "IFAD", "IFC", "IFRCS", "IHO", "ILO", "IMF", "IMO", "Inmarsat", "Intelsat", "Interpol",
                                 "IOC", "IOM", "ISO", "ITU", "MONUC", "NAM (guest)", "NATO", "NEA", "NSG", "OAS (observer)", "OECD", "OPCW",
                                 "OSCE", "PCA", "UN", "UNCTAD", "UNESCO", "UNHCR", "UNIDO", "UNIKOM", "UNMIBH", "UNMIK", "UNOMIG",
                                 "UPU", "WADB (nonregional)", "WEU", "WHO : World Health Organization",
                                 "WIPO : World Intellectual Property Organization", "WMO", "WToO", "WTrO", "ZC"};
  private String[] orgItaly = {"AfDB", "AsDB", "Australia Group", "BIS", "BSEC (observer)", "CCC", "CDB (non-regional)", "CE", "CEI", "CERN", "EAPC", "EBRD",
                               "ECE", "ECLAC", "EIB", "EMU", "ESA", "EU", "FAO", "G- 7", "G-10", "IADB", "IAEA", "IBRD", "ICAO", "ICC", "ICFTU", "ICRM", "IDA", "IEA",
                               "IFAD", "IFC", "IFRCS", "IHO", "ILO", "IMF", "IMO", "Inmarsat", "Intelsat", "Interpol", "IOC", "IOM", "ISO", "ITU", "LAIA (observer)",
                               "MINURSO", "NAM (guest)", "NATO", "NEA", "NSG", "OAS (observer)", "OECD", "OPCW", "OSCE", "PCA", "UN", "UNCTAD",
                               "UNESCO", "UNHCR", "UNIDO", "UNIFIL", "UNIKOM", "UNMEE", "UNMIBH", "UNMIK", "UNMOGIP", "UNTSO", "UPU", "WCL", "WEU",
                               "WHO", "WIPO", "WMO", "WToO", "WTrO", "ZC"};

	private CityData capitalGer;
	private CityDataInterface[] cityDataGer = {
																		new CityData("Aachen",6.10f,50.77f,247113, false),
                                    new CityData("Augsburg",10.90f,48.35f,262110, false),
                                    new CityData("Bergisch Gladbach",7.17f,50.98f,105122, false),
                                    capitalGer = new CityData("Berlin",13.42f,52.53f,3472009, true),
                                    new CityData("Bielefeld",8.53f,52.03f,324067, false),
                                    new CityData("Bochum",7.18f,51.47f,401129, false),
                                    new CityData("Bonn",7.10f,50.73f,293072, true),
                                    new CityData("Bottrop",6.92f,51.52f,119669, false),
                                    new CityData("Braunschweig",10.50f,52.25f,254130, false),
                                    new CityData("Bremen",8.80f,53.08f,549122, true),
                                    new CityData("Bremerhaven",8.58f,53.55f,130847, true),
                                    new CityData("Chemnitz",12.92f,50.83f,274162, false),
                                    new CityData("Cottbus",14.35f,51.72f,125643, false),
                                    new CityData("Darmstadt",8.65f,49.87f,139063, false),
                                    new CityData("Dortmund",7.45f,51.53f,600918, false),
                                    new CityData("Dresden",13.75f,51.05f,474443, true),
                                    new CityData("Duisburg",6.75f,51.43f,536106, true),
                                    new CityData("D�sseldorf",6.78f,51.22f,572638, false),
                                    new CityData("Erfurt",11.03f,50.97f,213472, false),
                                    new CityData("Erlangen",11.03f,49.60f,101450, false),
                                    new CityData("Essen",6.98f,51.47f,617955, false),
                                    new CityData("Frankfurt am Main",8.68f,50.10f,652412, false),
                                    new CityData("Freiburg im Breisgau",7.87f,48.00f,198496, false),
                                    new CityData("F�rth",11.00f,49.47f,107799, false),
                                    new CityData("Gelsenkirchen",7.08f,51.50f,293542, false),
                                    new CityData("Gera",12.18f,50.85f,126035, false),
                                    new CityData("G�ttingen",9.92f,51.52f,127519, false),
                                    new CityData("Hagen",7.48f,51.35f,213747, false),
                                    new CityData("Halle",11.97f,51.47f,290051, false),
                                    new CityData("Hamburg",10.00f,53.55f,1705872, true),
                                    new CityData("Hamm",7.82f,51.67f,184020, false),
                                    new CityData("Hannover",9.73f,52.23f,525763, false),
                                    new CityData("Heidelberg",8.70f,49.42f,138964, false),
                                    new CityData("Heilbronn",9.23f,49.13f,122253, false),
                                    new CityData("Herne",7.20f,51.53f,180029, false),
                                    new CityData("Hildesheim",9.97f,52.15f,106095, false),
                                    new CityData("Ingolstadt",11.45f,48.77f,110910, false),
                                    new CityData("Jena",11.58f,50.93f,102204, false),
                                    new CityData("Kaiserslautern",7.75f,49.45f,101910, false),
                                    new CityData("Karlsruhe",8.40f,49.00f,277011, true),
                                    new CityData("Kassel",9.50f,51.30f,201789, false),
                                    new CityData("Kiel",10.13f,54.33f,246586, true),
                                    new CityData("Koblenz",7.60f,50.35f,109550, false),
                                    new CityData("K�ln",6.95f,50.93f,963817, true),
                                    new CityData("Krefeld",6.53f,51.33f,249662, false),
                                    new CityData("Leipzig",12.42f,51.33f,481121, false),
                                    new CityData("Leverkusen",6.98f,51.03f,161832, false),
                                    new CityData("L�beck",10.67f,53.87f,216854, true),
                                    new CityData("Ludwigshafen am Rhein",8.45f,49.48f,167883, false),
                                    new CityData("Magdeburg",11.62f,52.13f,265379, true),
                                    new CityData("Mainz",8.27f,50.00f,184627, false),
                                    new CityData("Mannheim",8.47f,49.50f,316223, true),
                                    new CityData("Moers",6.65f,51.45f,107011, false),
                                    new CityData("M�nchengladbach",6.42f,51.20f,266073, false),
                                    new CityData("M�lheim a.d. Ruhr",6.83f,51.42f,176513, false),
                                    new CityData("M�nchen",11.58f,48.13f,1244676, false),
                                    new CityData("M�nster",7.62f,51.97f,264887, false),
                                    new CityData("Neuss",6.70f,51.20f,148870, false),
                                    new CityData("N�rnberg",11.08f,49.45f,495845, false),
                                    new CityData("Oberhausen",6.83f,51.47f,225443, false),
                                    new CityData("Offenbach am Main",8.77f,50.10f,116482, false),
                                    new CityData("Oldenburg",8.22f,53.13f,149691, false),
                                    new CityData("Osnabr�ck",8.05f,52.28f,168050, false),
                                    new CityData("Paderborn",8.73f,51.72f,131513, false),
                                    new CityData("Pforzheim",8.68f,48.88f,117960, false),
                                    new CityData("Potsdam",13.07f,52.40f,138268, false),
                                    new CityData("Recklinghausen",7.18f,51.62f,127139, false),
                                    new CityData("Regensburg",12.12f,49.02f,125608, false),
                                    new CityData("Remscheid",7.18f,51.17f,123069, false),
                                    new CityData("Reutlingen",9.22f,48.48f,107782, false),
                                    new CityData("Rostock",12.15f,54.07f,232634, true),
                                    new CityData("Saarbr�cken",6.97f,49.25f,189012, false),
                                    new CityData("Salzgitter",10.33f,52.22f,117842, false),
                                    new CityData("Schwerin",11.42f,53.63f,118291, false),
                                    new CityData("Siegen",8.03f,50.87f,111541, false),
                                    new CityData("Solingen",7.08f,51.17f,165973, false),
                                    new CityData("Stuttgart",9.20f,48.78f,588482, true),
                                    new CityData("Ulm",10.00f,48.40f,115123, false),
                                    new CityData("Wiesbaden",8.25f,50.08f,266081, false),
                                    new CityData("Witten",7.32f,51.42f,105423, false),
                                    new CityData("Wolfsburg",10.82f,52.45f,126965, false),
                                    new CityData("Wuppertal",7.17f,51.25f,383776, false),
                                    new CityData("W�rzburg",9.95f,49.80f,127946, false),
                                    new CityData("Zwickau",12.05f,50.72f,104921, false)}; 
  
  
  private HashMap<String, CountryData> countryData = new HashMap<String, CountryData>();
  private HashMap<String, HashSet<String>> countryOrgs = new HashMap<String, HashSet<String>>();
  private HashMap<String, HashMap<String, String[]>> statData = new HashMap<String, HashMap<String, String[]>>();
  
  /** Konstruktor */
  public DummyImpl () {
    countryData.put(COUNTRY_NAME_DE,
                       new CountryData("Germany", "Federal Republic of Germany",(float)-9.00, (float)51.00,
                                    "As Western Europe's richest and most populous nation, Germany remains a key member of the " +
                                    "continent's economic, political, and defense organizations. European power struggles immersed " +
                                    "the country in two devastating World Wars in the first half of the 20th century and left the " +
                                    "country occupied by the victorious Allied powers of the US, UK, France, and the Soviet Union in " +
                                    "1945. With the advent of the Cold War, two German states were formed in 1949: the western " +
                                    "Federal Republic of Germany (FRG) and the eastern German Democratic Republic (GDR). The " +
                                    "democratic FRG embedded itself in key Western economic and security organizations, the EC " +
                                    "and NATO, while the communist GDR was on the front line of the Soviet-led Warsaw Pact. The " +
                                    "decline of the USSR and the end of the Cold War allowed for German unification in 1990. Since " +
                                    "then Germany has expended considerable funds to bring eastern productivity and wages up to " +
                                    "western standards. In January 1999, Germany and 10 other EU countries formed a common " +
                                    "European currency, the euro.",
                                    "Central Europe, bordering the Baltic Sea and the North Sea, between the Netherlands and " +
                                    "Poland, south of Denmark",
                                    "figures/gm-flag.jpg", "figures/gm-map.jpg",
                                    capitalGer, "kein Kommentar", asOrgs(orgGermany)));
		countryData.get(COUNTRY_NAME_DE).setCities(Arrays.asList(cityDataGer));
    countryOrgs.put(COUNTRY_NAME_FR, new HashSet<String>(Arrays.asList(orgFrance)));
    countryOrgs.put(COUNTRY_NAME_DE, new HashSet<String>(Arrays.asList(orgGermany)));
    countryOrgs.put(COUNTRY_NAME_IT, new HashSet<String>(Arrays.asList(orgItaly)));
    statData.put(COUNTRY_NAME_FR, new HashMap<String, String[]>());
    (statData.get(COUNTRY_NAME_FR)).put("1999", statFrance1999);
    (statData.get(COUNTRY_NAME_FR)).put("2000", statFrance2000);
    statData.put(COUNTRY_NAME_DE, new HashMap<String, String[]>());
    (statData.get(COUNTRY_NAME_DE)).put("1999", statGermany1999);
    (statData.get(COUNTRY_NAME_DE)).put("2000", statGermany2000);
    statData.put(COUNTRY_NAME_IT, new HashMap<String, String[]>());
    (statData.get(COUNTRY_NAME_IT)).put("1999", statItaly1999);
    (statData.get(COUNTRY_NAME_IT)).put("2000", statItaly2000);
  }

	private List<OrganizationDataInterface> asOrgs(String[] orgNames) {
		ArrayList<OrganizationDataInterface> orgs = new ArrayList<OrganizationDataInterface>();
		for (String orgName : orgNames) {
			orgs.add(new OrganizationData(orgName, null));
		}
		return orgs;
	}

	/** Initialisierung der Zugriffsschicht. Das Property-Objekt
   * enthaelt alle notwendigen Parameter.
   * @param prop  Property-Objekt mit Attribut-Wert-Paaren, die
   *              zur Initialisierung dienen (Login-Name, Passwort,...).
   */
  public void init(Properties prop) { // in dem Properties objekt sind die verbindungsdaten, 
	  									//also treiber, username und pw
    // drucke Properties aus
    System.out.println("Properties:");
    prop.list(System.out);
    this.prop=prop;
  }

  /** Diese Methode wird bei Beendigung der Anwendung aufgerufen. Hier koennen
   * alle Ressourcen freigegeben werden (Verbindung usw.) 
   */
  public void finish() {
    System.out.println("DummyImpl: finished.");
  }
  
  // -- Staedte- und Laenderdaten abfragen -----------------------------------
  /** Liefert eine Liste aller Laendernamen, die zu dem gegebenen Pattern
   * (Suchausdruck) passen.
   * @param namePattern  der Suchausdruck, der die zu liefernden Namen
   *                     bestimmt; Wildcards entsprechen dem
   *                     SQL-Standard; namePattern kann <code>null</code> sein!
   * @return Liste von Laendernamen, die auf den Suchausdruck passen oder
   *         im Falle, dass <code>namePattern==null</code>, die Liste aller
   *         Laendernamen; die Listenobjekte sind vom Typ String
   */
  public List<String> getCountries(String namePattern) {
    ArrayList<String> list = new ArrayList<String>();
    boolean returnAll = (namePattern == null);
		for (String country : countries) {
			if (returnAll) {
				list.add(country);
			} else {
				if ((namePattern.startsWith("%") &&
						country.endsWith(namePattern.substring(1))) ||
						(namePattern.endsWith("%") &&
								country.startsWith(
										namePattern.substring(0, namePattern.length() - 1))) ||
						country.equals(namePattern)) {
					list.add(country);
				}
			}
		}
		return list;
  }
  
  /** Liefert ein Objekt mit Daten zu einem Land.
   * @param countryName  Name des Landes, von dem die Daten geliefert
   *                     werden sollen
   * @return zeitunabhaengige Daten zu dem angegebenen Land
   *         (im Wesentlichen Attribute der Landes-Tabelle) oder
   *         <code>null</code> wenn kein Land mit diesem Namen existiert
   */
  public CountryDataInterface getCountryData(String countryName) {

    return countryData.get(countryName);
  }
  
  // -- Weitere Daten der Datenbank abfragen ---------------------------------
  /** Liefert eine Liste aller Organisationen.
   * @return Liste der Abkuerzungen aller in der Datenbank enthaltenen
   *         Organisationen; die Listenobjekte sind vom Typ String
   */
  //@anotations für hibernate an alle getter...
  public List<String> getOrganizations() {

    // gebe Liste der Organisationen von Deutschland zurueck
    return Arrays.asList(orgGermany);
  }
  
  /** Liefert die ausfuehrlichen Namen aller Attribute, die in der
   * Statisitk-Tabelle verfuegbar sind (z.B. BIP, Einwohnerzahl, ...).
   * @return Liste von Attributnamen der Statisitk-Tabelle (ohne Attribut Jahr)
   */
  public List<String> getStatisticAttributes() {

    return Arrays.asList(statAttrs);
  }

  /** Liefert alle Jahre, zu denen Daten in der Statistik-Tabelle verfuegbar sind.
   * @return Liste von Jahren zu denen es Eintraege in der Statisitk-Tabelle gibt
   */
  public List<String> getStatisticYears() {

    return Arrays.asList(statYears);
  }
  
  /** Liefert die statistischen Daten fuer alle angegebenen Laender und alle angegebenen
   * Jahre. Es werden nur diejenigen Laender zurueckgeliefert, die den Bedingungen
   * entsprechen, dass sie in allen Organisationen vertreten sind, die in inOrganization
   * angegeben sind und in keiner Organisation vertreten sind, die in notInOrganization
   * angegeben sind. Weiterhin sollen nur die statistischen Attribute zurueckgeliefert
   * werden, die in attributes spezifiziert wurden.
   *
   * @param countries  die Laender, die als potentielle Kandidaten fuer die statistischen
   *                   Daten in Frage kommen (beachte Auswahlkriterium Organisation!);
   *                   wird hier <code>null</code> uebergeben, kommen alle Laender als
   *                   Kandidaten in Frage
   * @param years      die Jahrgaenge fuer die statistische Daten geliefert werden sollen;
   *                   wird hier <code>null</code> angegeben, sollen alle verfuegbaren
   *                   Jahrgaenge geliefert werden
   * @param inOrganization  eine Liste von Organisationen; Laender fuer die statistische
   *                        Daten geliefert werden sollen, muessen in allen hier gelisteten
   *                        Organisationen vertreten sein (Filterkriterium fuer die
   *                        angegeben Laender);
   *                        wird hier <code>null</code> uebergeben, ist dieses
   *                        Filterkriterium nicht wirksam
   * @param notInOrganization  eine Liste von Organisationen; Laender fuer die statistische
   *                           Daten geliefert werden sollen, duerfen in keiner hier
   *                           gelisteten Organisationen vertreten sein (Filterkriterium
   *                           fuer die angegeben Laender);
   *                           wird hier <code>null</code> uebergeben, ist dieses
   *                           Filterkriterium nicht wirksam
   * @param attributes  eine Auswahl der statistischen Daten, die geliefert werden sollen;
   *                    wird hier <code>null</code> uebergeben, sollen alle Attribute
   *                    geliefert werden
   * @return Datenobjekt, das alle gewuenschten statistischen Informationen fuer alle
   *         Laender, die den Filterkriterien entsprechen und alle angegeben Jahrgaenge
   *         enthaelt 
   */
  public StatData getStatisticData(String[] countries, String[] years,
                                   String[] inOrganization,
                                   String[] notInOrganization,
                                   String[] attributes) {

     if ((countries != null) && (countries.length == 0)) countries = null;
     if ((years != null) && (years.length == 0)) years = null;
     if ((inOrganization != null) && (inOrganization.length == 0)) inOrganization = null;
     if ((notInOrganization != null) && (notInOrganization.length == 0)) notInOrganization = null;
     if ((attributes != null) && (attributes.length == 0)) attributes = null;
     
     HashSet<String> retCountries;
     
     if (countries == null)
       countries = this.countries;

     retCountries = new HashSet<String>();
     HashSet<String> allCountries = new HashSet<String>(Arrays.asList(this.countries));

		for (String country : countries) {
			if (allCountries.contains(country)) {
				boolean addCountry = true;
				if (inOrganization != null)
					for (String anInOrganization : inOrganization) {
						if (!(countryOrgs.get(country)).contains(anInOrganization)) {
							addCountry = false;
							break;
						}
					}
				if (addCountry && (notInOrganization != null))
					for (String aNotInOrganization : notInOrganization) {
						if ((countryOrgs.get(country)).contains(aNotInOrganization)) {
							addCountry = false;
							break;
						}
					}
				if (addCountry) retCountries.add(country);
			}
		}
		List<String> retAttrs = (attributes == null) ? Arrays.asList(statAttrs) : Arrays.asList(attributes);
     int[] attrSeq = new int[retAttrs.size()];
     for (int i=0; i<retAttrs.size(); i++) {
       for (int j=0; j<statAttrs.length; j++) {
         if ((retAttrs.get(i)).equals(statAttrs[j])) {
           attrSeq[i] = j;
           break;
         }     
       }
     }
     StatData retStatData = new StatData((String[])retAttrs.toArray());
     String[] retYears = (years == null) ? statYears : years;
     Iterator<String> cIter = retCountries.iterator();
     String country;
     String[] attrs;
     String[] attrsOrdered;
     while(cIter.hasNext()) {
       country = cIter.next();
			 for (String retYear : retYears) {
				 attrs = (statData.get(country)).get(retYear);
				 attrsOrdered = new String[retAttrs.size()];
				 for (int i = 0; i < attrsOrdered.length; i++) {
					 attrsOrdered[i] = attrs[attrSeq[i]];
				 }
				 try {
					 retStatData.addData(country, retYear, attrsOrdered);
				 } catch (WfbDbException e) {
					 System.err.println(e.getMessage());
				 }
			 }
		 }
     
     return retStatData;
  }
    
  // -- Update-Operation -----------------------------------------------------
  /** Ersetzt einen Kommentar zu einem Land durch einen neuen Kommentar.
   * @param country  das Land fuer das der Kommentar ersetzt werden soll
   * @param comment der neue Kommentar
   * @exception WfbDbException  wenn waehrend der Operation ein Fehler auftrat
   */
  public void updateCountryComment(String country, String comment) throws WfbDbException {

    CountryData cData;
    if ((cData = countryData.get(country)) != null)
      cData.setComment(comment);
  }
    
  // -- Direkter Datenbankzugriff --------------------------------------------
  /** Fuehrt die gegebene Operation auf der Datenbank aus und liefert
   * das Ergebnis in einem SQLResultInterface-Objekt aufbereitet zurueck.<br>
   * Achtung: es kann sich bei der Operation sowohl um eine Anfrage als auch
   *          um eine Aenderungsoperation (insert, drop, ...) handeln. Dieses
   *          muss beruecksichtigt werden (Hinweis: Statement.execute()). Je
   *          nach Art der Operation wird das Anfrageergebnis oder numerische
   *          Rueckgabewert der Aenderungsoperation von der Methode zurueckgegeben.
   * @param query  die auszufuehrende Operation
   * @return das Ergebnis der Operation als SQLResultInterface-Objekt; entweder
   *         das Anfrageergebnis oder der numerische Wert bei einer Update-Operation
   * @exception WfbDbException  wenn waehrend der Ausfuehrung der Anfrage
   *                            ein Fehler auftrat (z.B. java.sql.SQLException)
   */
  public SQLResultInterface executeSqlQuery(String query) throws WfbDbException {
    class SQLResImpl implements SQLResultInterface{
      String[] attrNames = null;
      String[][] rows = null;
      int row = -1;
      SQLResImpl(String[] attrNames, String[][] rows) {
        this.attrNames=attrNames;
        this.rows = rows;
      }
      public List<String> getHeader() throws WfbDbException {
        return Arrays.asList(attrNames);
      }
      public String[] getNextRow() throws WfbDbException {
        return (++row < rows.length) ? rows[row] : null;
      }
    }

    // definiere 3 verschiedene Ergebnisse (abhaengig von Laenge der Anfrage)
    if ((query == null) || (query.length()==0))
      throw new WfbDbException("Keine Anfrage uebergeben!");
    if ((query.length() % 3) == 0) {
      return new SQLResImpl(sqlHead1, sqlRows1);
    } else if ((query.length() % 3) == 1) {
      return new SQLResImpl(sqlHead2, sqlRows2);
    } else {
      return new SQLResImpl(sqlHead3, sqlRows3);
    }
  }

	// -- Direkter Datenbankzugriff per HQL ------------------------------------
	public SQLResultInterface executeHqlQuery(String query, boolean deref) throws WfbDbException {
		// in diesem Beispiel behandeln wir einfach mal den HQL-Query als SQL-Query
		return executeSqlQuery(query);
	}
}
